package com.eling.elcms.travel.model;

import com.eling.elcms.basedoc.model.EnumSerializer;
import com.eling.elcms.core.dao.annotation.In;
import com.eling.elcms.core.dao.hibernate.search.EnumBridge;
import com.eling.elcms.core.model.BaseModel;
import com.eling.elcms.ordermanager.model.ServicePoint;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.hibernate.search.annotations.*;

import javax.persistence.*;
import java.util.Date;
import java.util.Set;

/**
 * 旅游团和联盟、服务点关系
 * 
 * @author zhoulin
 *
 */
@Entity
@Table(name = "travel_planitemgroup")
@Indexed
public class PlanItemGroup extends BaseModel {

	private static final long serialVersionUID = 5517391252287698255L;

	@Id
	@In
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@DocumentId
	private Long pkPlanItemGroup;

	/** 联盟单位 */
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "pkAllianceOrg")
	@IndexedEmbedded(depth = 1)
	private AllianceOrg allianceOrg;

	/** 报名团 */
	@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
	@JoinColumn(name = "pkPlanItem")
	@IndexedEmbedded(depth = 1)
	@In
	private PlanItem planItem;

	/** 服务点 */
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "pkServicePoint")
	@IndexedEmbedded(depth = 1)
	private ServicePoint servicePoint;

	/** 是否联盟 */
	@Field
	@Column
	private Boolean alliance;

	/** 报名状态 */
	@Enumerated(EnumType.STRING)
	@Field
	@In
	@FieldBridge(impl = EnumBridge.class)
	private SignUpStatus signUpStatus;

	/** 预约入住状态 */
	@Enumerated(EnumType.STRING)
	@Field
	@In
	@FieldBridge(impl = EnumBridge.class)
	private CheckInStatus checkInStatus;

	/** 报名信息 */
	@OneToMany
	@JoinColumn(name = "pkPlanItemGroup")
	@IndexedEmbedded(depth = 1)
	private Set<SignUpRegister> signUps;
	
	/** 房型信息*/
	/** 直属机构房间 */
	@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
	@IndexedEmbedded(depth = 1)
	@JoinTable(name = "travel_group_signuproomtypecount", joinColumns = @JoinColumn(name = "pkPlanItemGroup"), inverseJoinColumns = @JoinColumn(name = "pkSignUpRoomTypeCount"))
	private Set<SignUpRoomTypeCount> signUpRoomTypeCounts;

	/** 备注 */
	@Column
	@Field
	private String description;

	/** 应收 */
	@Column
	@Field
	private Double payable;

	/** 是否调整 */
	@Column
	@Field
	private Boolean isAdjustment;

	/** 调整日期 */
	@Column
	@Field
	private Date adjustDate;

	/** 是否整团取消 */
	@Column(columnDefinition = "bigint default 0")
	@Field
	private Boolean isAbolished;

	/** 调整类型 */
	@ElementCollection(fetch = FetchType.LAZY)
	@Enumerated(EnumType.STRING)
	@CollectionTable(name = "travel_mem_adjusttypes", joinColumns = @JoinColumn(name = "pkMemGroup"))
	@Column(name = "adjusttypes", nullable = false)
	private Set<AdjustType> adjustTypes;

	@Version
	private Integer version;

	/** 预约入住状态 */
	@JsonSerialize(using = EnumSerializer.class)
	public static enum CheckInStatus {
		Initial("待预约"), Reserve("已预约"), CheckIn("已入住"), Finish("已结束");

		private String display;

		CheckInStatus(String display) {
			this.display = display;
		}

		public String getDisplay() {
			return display;
		}
	}

	/** 报名状态 */
	@JsonSerialize(using = EnumSerializer.class)
	public static enum SignUpStatus {
		Confirm("确认"), Review("已复核"), AdjustmentReview("调整复核");

		private String display;

		SignUpStatus(String display) {
			this.display = display;
		}

		public String getDisplay() {
			return display;
		}
	}

	/** 获取报名人数，不包括已退团人员 */
	public Integer getSignUpNum() {
		if (signUps != null && signUps.size() != 0) {
			int count = 0;
			for (SignUpRegister signUpRegister : signUps) {
				count += signUpRegister.getExitGroup() == null || !signUpRegister.getExitGroup() ? 1 : 0;
			}
			return count;
		} else {
			return 0;
		}

	}

	public Long getPkPlanItemGroup() {
		return pkPlanItemGroup;
	}

	public void setPkPlanItemGroup(Long pkPlanItemGroup) {
		this.pkPlanItemGroup = pkPlanItemGroup;
	}

	public AllianceOrg getAllianceOrg() {
		return allianceOrg;
	}

	public void setAllianceOrg(AllianceOrg allianceOrg) {
		this.allianceOrg = allianceOrg;
	}

	public PlanItem getPlanItem() {
		return planItem;
	}

	public void setPlanItem(PlanItem planItem) {
		this.planItem = planItem;
	}

	public ServicePoint getServicePoint() {
		return servicePoint;
	}

	public void setServicePoint(ServicePoint servicePoint) {
		this.servicePoint = servicePoint;
	}

	public Boolean getAlliance() {
		return alliance;
	}

	public void setAlliance(Boolean alliance) {
		this.alliance = alliance;
	}

	public SignUpStatus getSignUpStatus() {
		return signUpStatus;
	}

	public void setSignUpStatus(SignUpStatus signUpStatus) {
		this.signUpStatus = signUpStatus;
	}

	public CheckInStatus getCheckInStatus() {
		return checkInStatus;
	}

	public void setCheckInStatus(CheckInStatus checkInStatus) {
		this.checkInStatus = checkInStatus;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public Set<SignUpRegister> getSignUps() {
		return signUps;
	}

	public void setSignUps(Set<SignUpRegister> signUps) {
		this.signUps = signUps;
	}

	public Integer getVersion() {
		return version;
	}

	public void setVersion(Integer version) {
		this.version = version;
	}

	public Double getPayable() {
		return payable;
	}

	public void setPayable(Double payable) {
		this.payable = payable;
	}

	public Boolean getIsAdjustment() {
		return isAdjustment;
	}

	public void setIsAdjustment(Boolean isAdjustment) {
		this.isAdjustment = isAdjustment;
	}

	public Date getAdjustDate() {
		return adjustDate;
	}

	public void setAdjustDate(Date adjustDate) {
		this.adjustDate = adjustDate;
	}

	public Boolean getIsAbolished() {
		return isAbolished;
	}

	public void setIsAbolished(Boolean isAbolished) {
		this.isAbolished = isAbolished;
	}

	public Set<AdjustType> getAdjustTypes() {
		return adjustTypes;
	}

	public void setAdjustTypes(Set<AdjustType> adjustTypes) {
		this.adjustTypes = adjustTypes;
	}

	public Set<SignUpRoomTypeCount> getSignUpRoomTypeCounts() {
		return signUpRoomTypeCounts;
	}

	public void setSignUpRoomTypeCounts(Set<SignUpRoomTypeCount> signUpRoomTypeCounts) {
		this.signUpRoomTypeCounts = signUpRoomTypeCounts;
	}

}
